﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHDay_Linq.Domain;
using NHibernate;
using NHibernate.Linq;
using NUnit.Framework;
     
namespace NHDay_Linq
{
	[TestFixture]
	public class T04_CustomUserType_HeldItems : TestBase
	{
		[TestFixtureSetUp]
		public void FixtureSetup()
		{
			CreateDatabase();
		}

		[Test]
		public void T01_QueryWithHql_Property_RightHand()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				Item item = (new Items())[0];
				var qry = session.CreateQuery("from Person p where p.RightHand = (:itm)");
				qry.SetParameter("itm", item);
				var magnus = qry.UniqueResult<Person>();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T02_QueryWithHql_Collection()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				Item item = (new Items())[0];
				var qry = session.CreateQuery("from Person p join p.HeldItems hi where hi in (:itms)");
				qry.SetParameterList("itms", new[] { item });
				var magnus = qry.UniqueResult<Person>();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T03_QueryWithLinq_Property_RightHand()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				Item item = (new Items())[0];
				var magnus = session.Query<Person>().Where(t => t.RightHand == item).FirstOrDefault();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T04_QueryWithLinq_Collection_1()
		{
			// Linq provider parser error
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				Items items = (new Items());
				var magnus = session.Query<Person>().Where(t => items.Any(i =>  t.HeldItems.Contains(i))).FirstOrDefault();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T05_QueryWithLinq_Collection_2()
		{
			// Linq provider parser error
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				Items items = (new Items());
				var magnus = session.Query<Person>().Where(t => t.HeldItems.Any(i => items.Contains(i))).FirstOrDefault();

				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}

		[Test]
		public void T06_QueryWithLinq_Collection_UsingLinqToObject()
		{
			using (ISession session = SessionFactory.OpenSession())
			using (ITransaction tx = session.BeginTransaction())
			{
				Item item = (new Items())[0];
				// linq to NHibernate
				List<Person> persons = session.Query<Person>().ToList();
				// lint to object here!
				Items items = (new Items());
				var magnus = persons.Where(t => items.Any(i => t.HeldItems.Contains(i))).FirstOrDefault();

                   
				Assert.IsNotNull(magnus);
				Assert.AreEqual("Magnus", magnus.FirstName);

				tx.Commit();
			}
		}
	}
}
